﻿using System.Diagnostics.Contracts;
using DomainExample.DomainModel;
using DomainExample.Repository.Exceptions;

namespace DomainExample.Repository
{
    [ContractClass(typeof(ContractsForIRepository<,>))]
    public interface IRepository<T, in TId> where T : IEntity
    {
        T GetById(TId id);
        T Persist(T entity);
        void Remove(TId id);
    }

    [ContractClassFor(typeof(IRepository<,>))]
    internal abstract class ContractsForIRepository<T, TId> : IRepository<T, TId> where T : IEntity
    {
        private ContractsForIRepository()
        {
            
        } 

        public T GetById(TId id)
        {
            Contract.Requires<InvalidEntityException>(id != null, "Entity Id is null");
            return default(T);
        }

        public T Persist(T entity)
        {
            Contract.Requires<InvalidEntityException>(entity != null, "Entity is null");
            // TODO: can we use: Contract.Requires<InvalidEntityException>(entity.IsValidForPersistence(), "Entity not valid for persistence " + entity.ToString());
            Contract.Requires<InvalidEntityException>(entity.IsValidForPersistence(), "Entity not valid for persistence");
            return default(T);
        }

        public void Remove(TId id)
        {
            Contract.Requires<InvalidEntityException>(id != null, "Entity Id is null");
        }
    }
}
